package com.ibm.cloud.banking.account.service;

import com.ibm.cloud.banking.account.convert.AccountInfoMapper;
import com.ibm.cloud.banking.account.convert.AccountOpenCloseDetailMapper;
import com.ibm.cloud.banking.account.dto.AccountInfoDTO;
import com.ibm.cloud.banking.account.entity.AccountInfo;
import com.ibm.cloud.banking.account.entity.AccountInfoEntity;
import com.ibm.cloud.banking.account.entity.AccountOpenCloseDetailEntity;
import com.ibm.cloud.banking.account.repository.AccountInfoRepository;
import com.ibm.cloud.banking.account.repository.AccountOpenCloseDetailRepository;
import com.ibm.cloud.banking.media.repository.MediaCardAccountRelRepository;
import com.ibm.cloud.banking.platform.exception.BusinessException;

import org.slf4j.MDC;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.Map;
import java.util.Optional;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;

import static com.ibm.cloud.banking.account.constant.AccountDomainConstant.OPEN_ACCOUNT_REVERSE_KEY;

/**
 * replace desc in here
 *
 * @author HanDong
 * @date 2022/7/18
 */
@Service
@Slf4j
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = RuntimeException.class)
public class AccountInfoServiceImpl implements  IAccountInfoService{


    @Resource
    private AccountInfoMapper accountInfoMapper;

    @Resource
    private AccountOpenCloseDetailMapper accountOpenCloseDetailMapper;

    @Resource
    private AccountInfoRepository accountInfoRepository;

    @Resource
    private AccountOpenCloseDetailRepository accountOpenCloseDetailRepository;

    @Override
    public AccountInfoDTO getAccountInfo(String accountNo) {
        Optional<AccountInfoEntity> optionalAccountInfoEntity = accountInfoRepository.findByAccountNo(accountNo);
        if(optionalAccountInfoEntity.isPresent())
        {
            return accountInfoMapper.entityToDto(optionalAccountInfoEntity.get());
        }else
        {
            throw new BusinessException("ACCOUNT-001","账户不存在");
        }
    }

    @Override
    public void createAccount(AccountInfoDTO accountInfoDTO) {

        accountInfoDTO.setCreateDt(new Timestamp(new java.util.Date().getTime()));
        accountInfoDTO.setType(AccountInfo.DEFAULT_SETTLEMENT_TYPE);
        accountInfoDTO.setStatus(AccountInfo.ACCOUNT_DEFAULT_STATUS);
        accountInfoDTO.setControlStatus(AccountInfo.ACCOUNT_CONTROL_STATUS_NORMAL);
        accountInfoDTO.setInterestFlag(AccountInfo.INTEREST_FLAG_Y);
        accountInfoDTO.setDetailCount(0);
        BigDecimal defaultBalance = new BigDecimal(0);
        accountInfoDTO.setBalance(defaultBalance.toBigInteger());
        accountInfoDTO.setOverdraftBalance(defaultBalance.toBigInteger());
        accountInfoDTO.setAvailableBalance(defaultBalance.toBigInteger());
        accountInfoDTO.setFreezeBalance(defaultBalance.toBigInteger());

        AccountInfoEntity accountInfoEntity = accountInfoMapper.dtoToEntity(accountInfoDTO);
        accountInfoEntity.setCurrency(AccountInfo.DEFAULT_CURRENCY_RMB);
        accountInfoEntity.setId(null);
        accountInfoRepository.save(accountInfoEntity);

        String accountNo = accountInfoEntity.getAccountNo();
        /**
         * 补偿信息放入上下文
         */
        MDC.put(OPEN_ACCOUNT_REVERSE_KEY,accountInfoEntity.getId().toString());

        AccountOpenCloseDetailEntity accountOpenCloseDetailEntity = accountOpenCloseDetailMapper.accountInfoDtoToEntity(accountInfoDTO);
        accountOpenCloseDetailEntity.setAccountNo(accountNo);
        accountOpenCloseDetailEntity.setTransType(AccountInfo.ACCOUNT_OPERATION_OPEN);
        accountOpenCloseDetailEntity.setTransDate(accountInfoDTO.getInitialDate());
        accountOpenCloseDetailEntity.setSystemDate(new Date(new java.util.Date().getTime()));

        accountOpenCloseDetailRepository.save(accountOpenCloseDetailEntity);
        /**
         * MUSE 的初始化逻辑
         */


        //return accountInfoDTO.getAccountNo();
    }



    // TODO 补偿应该按领域拆在不同domain
    @Resource
   private MediaCardAccountRelRepository mediaCardAccountRelRepository;



    @Override
    public void reverseAccount(AccountInfoDTO accountInfoDTO) {
       String accountNo = accountInfoDTO.getAccountNo();
       Optional<AccountInfoEntity> optionalAccountInfoEntity = accountInfoRepository.findByAccountNo(accountNo);
       if(optionalAccountInfoEntity.isPresent())
       {
          AccountInfoEntity accountInfoEntity = optionalAccountInfoEntity.get();

           /**
            * 清除accountOpenCloseDetail
            */
           accountOpenCloseDetailRepository.deleteByAccountNo(accountNo);

           /**
            * 清除mediaCardAccountRel
            */
           mediaCardAccountRelRepository.deleteByAccountNo(accountNo);

           accountInfoRepository.delete(accountInfoEntity);
       }else
       {
           log.info("Account 数据不存在，无需补偿");
       }
    }
}
